package org.base23.video.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.base23.video.domain.dto.FrameAnalysisApiResponse;
import org.base23.video.domain.dto.VideoAnalysisApiResponse;
import org.base23.video.domain.dto.VideoAnalysisResult;
import org.base23.video.service.VideoAnalysisApiService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import org.base23.video.domain.dto.ExternalApiResultResponse;

/**
 * 外部视频分析API服务实现
 */
@Service
@Slf4j
public class VideoAnalysisApiServiceImpl implements VideoAnalysisApiService {
    
    private final RestTemplate restTemplate;
    private final String apiBaseUrl;
    
    public VideoAnalysisApiServiceImpl(@Value("${video.analysis.api.base-url:http://127.0.0.1:5000}") String apiBaseUrl) {
        this.restTemplate = new RestTemplate();
        this.apiBaseUrl = apiBaseUrl;
    }
    
    @Override
    public VideoAnalysisApiResponse analyzeVideo(MultipartFile videoFile) {
        log.info("开始上传视频进行分析，文件名: {}", videoFile.getOriginalFilename());
        
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            
            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            body.add("video", new ByteArrayResource(videoFile.getBytes()) {
                @Override
                public String getFilename() {
                    return videoFile.getOriginalFilename();
                }
            });
            
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
            
            ResponseEntity<VideoAnalysisApiResponse> response = restTemplate.postForEntity(
                    apiBaseUrl + "/api/analyze_video",
                    requestEntity,
                    VideoAnalysisApiResponse.class
            );
            
            log.info("视频分析请求完成，响应码: {}", response.getStatusCode());
            return response.getBody();
            
        } catch (IOException e) {
            log.error("读取视频文件失败: {}", e.getMessage(), e);
            throw new RuntimeException("读取视频文件失败", e);
        } catch (Exception e) {
            log.error("视频分析API调用失败: {}", e.getMessage(), e);
            throw new RuntimeException("视频分析API调用失败", e);
        }
    }
    
    @Override
    public FrameAnalysisApiResponse analyzeFrame(MultipartFile imageFile) {
        log.info("开始分析单帧图像，文件名: {}", imageFile.getOriginalFilename());
        
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            
            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            body.add("image", new ByteArrayResource(imageFile.getBytes()) {
                @Override
                public String getFilename() {
                    return imageFile.getOriginalFilename();
                }
            });
            
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
            
            ResponseEntity<FrameAnalysisApiResponse> response = restTemplate.postForEntity(
                    apiBaseUrl + "/api/analyze_frame",
                    requestEntity,
                    FrameAnalysisApiResponse.class
            );
            
            log.info("单帧分析请求完成，响应码: {}", response.getStatusCode());
            return response.getBody();
            
        } catch (IOException e) {
            log.error("读取图像文件失败: {}", e.getMessage(), e);
            throw new RuntimeException("读取图像文件失败", e);
        } catch (Exception e) {
            log.error("单帧分析API调用失败: {}", e.getMessage(), e);
            throw new RuntimeException("单帧分析API调用失败", e);
        }
    }
    
    @Override
    public VideoAnalysisResult.VideoAnalysisData getAnalysisResult(String resultId) {
        log.info("获取分析结果，结果ID: {}", resultId);
        
        try {
            // 先获取原始字符串响应进行调试
            ResponseEntity<String> rawResponse = restTemplate.getForEntity(
                    apiBaseUrl + "/api/result/" + resultId,
                    String.class
            );
            
            log.info("获取分析结果完成，响应码: {}", rawResponse.getStatusCode());
            
            String rawJson = rawResponse.getBody();
            System.out.println("=== 外部API原始响应 ===");
            System.out.println("原始JSON响应: " + rawJson);
            System.out.println("=== 原始响应结束 ===");
            
            if (rawJson == null || rawJson.trim().isEmpty()) {
                throw new RuntimeException("外部API返回空响应");
            }
            
            // 尝试解析为我们的格式
            try {
                // 方式1：尝试直接解析为包装格式
                ResponseEntity<ExternalApiResultResponse> response = restTemplate.getForEntity(
                        apiBaseUrl + "/api/result/" + resultId,
                        ExternalApiResultResponse.class
                );
                
                ExternalApiResultResponse apiResponse = response.getBody();
                if (apiResponse != null && apiResponse.getCode() == 200) {
                    return apiResponse.getData();
                }
            } catch (Exception e1) {
                log.warn("尝试解析包装格式失败: {}", e1.getMessage());
                
                // 方式2：尝试直接解析为VideoAnalysisData格式
                try {
                    ResponseEntity<VideoAnalysisResult.VideoAnalysisData> response2 = restTemplate.getForEntity(
                            apiBaseUrl + "/api/result/" + resultId,
                            VideoAnalysisResult.VideoAnalysisData.class
                    );
                    
                    return response2.getBody();
                } catch (Exception e2) {
                    log.error("所有解析方式都失败了");
                    log.error("方式1错误: {}", e1.getMessage());
                    log.error("方式2错误: {}", e2.getMessage());
                    throw new RuntimeException("无法解析外部API响应格式", e2);
                }
            }
            
            throw new RuntimeException("解析外部API响应失败");
            
        } catch (Exception e) {
            log.error("获取分析结果失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取分析结果失败", e);
        }
    }
    
    @Override
    public boolean isServiceAvailable() {
        try {
            ResponseEntity<String> response = restTemplate.getForEntity(
                    apiBaseUrl + "/",
                    String.class
            );
            return response.getStatusCode().is2xxSuccessful();
        } catch (Exception e) {
            log.warn("外部视频分析服务不可用: {}", e.getMessage());
            return false;
        }
    }
} 